/*******************************************************************************
 * Copyright (c) 2010 liw.
 * All rights reserved. 
 * 
 * This file is part of VanBus.
 * 
 *     VanBus is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     VanBus is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with VanBus.  If not, see <http://www.gnu.org/licenses/>.
 * Contributors:
 *     liw - initial API and implementation
 ******************************************************************************/
package org.niclab.vanbus.activity.controller;

import java.util.ArrayList;
import java.util.Calendar;

import org.niclab.vanbus.R;
import org.niclab.vanbus.database.ApplicationDataBase;
import org.niclab.vanbus.database.ReminderDAO;
import org.niclab.vanbus.model.BusRoute;
import org.niclab.vanbus.model.BusStop;
import org.niclab.vanbus.model.EndStopReminder;
import org.niclab.vanbus.model.Reminder;
import org.niclab.vanbus.model.StartStopReminder;
import org.niclab.vanbus.model.Reminder.ReminderType;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteConstraintException;
import android.location.LocationManager;
import android.net.Uri;
import android.util.Log;

public class ReminderController {
	
	private static final String LOG_TAG="ReminderController";


	public static final String REMINDER_ID = "org.niclab.reminder.startstop.reminderid";
	public static final String REMINDER_START_STOP_ALARM_INTENT_KEY_BUS_TIMES = "org.niclab.reminder.startstop.bustimes";
	public static final String REMINDER_START_STOP_ALARM_INTENT_KEY_BUS_STOP_NAME = "org.niclab.reminder.startstop.busstopname";
	public static final String REMINDER_START_STOP_ALARM_INTENT_KEY_BUS_STOP_ID = "org.niclab.reminder.startstop.busstopid";
	public static final String REMINDER_START_STOP_ALARM_INTENT_KEY_ROUTE_ID = "org.niclab.reminder.startstop.routeid";
	
	public static final String REMINDER_END_STOP_LOCATION_UPDATE_INTENT_KEY_SOURCE="org.niclab.reminder.endstop.intentsource";
	public static final String REMINDTER_END_STOP_LOCATION_UPDATE_INTENT_KEY_DATA="org.niclab.reminder.endstop.intentdata";
	
	public static final int REMINDER_END_STOP_INTENT_SRC_PROXIMITY_ALERT=1;
	public static final int REMINDER_END_STOP_INTENT_SRC_GPS_UPDATE=2;
	
	public static final int PROXIMITY_SERVICE_INTERVAL=240; //4 mins, 240 secs
	
	
	private Context context;
	
	public ReminderController(Context context){
		
		this.context = context;
	}
	
	public void setStartStopReminder(StartStopReminder reminder) throws SQLiteConstraintException{
		
		BusStop stop = reminder.getStop();
		BusRoute route = reminder.getRoute();
		
		AlarmManager alarmManager = (AlarmManager) context.getSystemService(Service.ALARM_SERVICE);
		
		Intent intent = new Intent(context.getString(R.string.reminder_intent_action_start_stop));
		//set data to this stop
		String prefix = context.getString(R.string.reminder_intent_data_uri_start_stop);
		intent.setData(Uri.parse(prefix + reminder.getReminderId()));
		
		ArrayList<String> times = (ArrayList<String>) stop.getTimes(route);
		intent.putStringArrayListExtra(REMINDER_START_STOP_ALARM_INTENT_KEY_BUS_TIMES, times);
		intent.putExtra(REMINDER_START_STOP_ALARM_INTENT_KEY_BUS_STOP_NAME, stop.getStopName());
		intent.putExtra(REMINDER_START_STOP_ALARM_INTENT_KEY_BUS_STOP_ID, stop.getStopId());
		intent.putExtra(REMINDER_START_STOP_ALARM_INTENT_KEY_ROUTE_ID, route.getRouteId());
		
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
		
		//insert a reminder record to database
		try{
			ReminderDAO rDao= new ReminderDAO(ApplicationDataBase.getSQLiteOpenHelper());
			rDao.insertReminder(reminder);
			alarmManager.set(AlarmManager.RTC_WAKEUP, reminder.getAlarmTime().getTime(), pendingIntent);
			Intent reminderUpdate = new Intent(context.getString(R.string.reminders_tab_start_stop_update));
			context.sendBroadcast(reminderUpdate);
		
		}catch(SQLiteConstraintException e){
			Log.d(LOG_TAG,"caught a SQLiteConstraintException");
			throw e;
		}
		
		
		
		Log.d(LOG_TAG, "a start stop reminder has been set");
		
	}

	
	public void deleteReminderByIdFromDB(ReminderType type, String reminderId){
		ReminderDAO rDao= new ReminderDAO(ApplicationDataBase.getSQLiteOpenHelper());

		rDao.deleteReminder(reminderId);
	/*	String t = reminderId.substring(0,1);
		Reminder.ReminderType type = Reminder.ReminderType.parseReminderType(t);*/
		//send change intent
		Intent removeReminderIntent =null;
		if(type == ReminderType.StartStopReminder)
			removeReminderIntent= new Intent(context.getString(R.string.reminders_tab_start_stop_update));
		else
			removeReminderIntent = new Intent(context.getString(R.string.reminders_tab_end_stop_update));
		context.sendBroadcast(removeReminderIntent);
	}
	
	public void deleteReminderByDBIdFromDB(ReminderType type,int dbId){
		ReminderDAO rDao= new ReminderDAO(ApplicationDataBase.getSQLiteOpenHelper());

		rDao.deleteReminder(dbId);
		//send change intent
		Intent removeReminderIntent =null;
		if(type == ReminderType.StartStopReminder)
			removeReminderIntent= new Intent(context.getString(R.string.reminders_tab_start_stop_update));
		else
			removeReminderIntent = new Intent(context.getString(R.string.reminders_tab_end_stop_update));
		context.sendBroadcast(removeReminderIntent);
	}
	
	public void cancelStartStopReminder(int dbId, String reminderId){
		Intent intent = new Intent(context.getString(R.string.reminder_intent_action_start_stop));
		//set data to this stop
		String prefix = context.getString(R.string.reminder_intent_data_uri_start_stop);
		intent.setData(Uri.parse(prefix +reminderId));
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
		AlarmManager alarmManager = (AlarmManager) context.getSystemService(Service.ALARM_SERVICE);
		alarmManager.cancel(pendingIntent);
		deleteReminderByDBIdFromDB(ReminderType.StartStopReminder, dbId);
		
	}
	

	
	public void setEndStopReminder(EndStopReminder reminder) throws SQLiteConstraintException{
		BusRoute route = reminder.getRoute();
		BusStop destStop = reminder.getDestStop();
		
		LocationManager locMgr = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
		
		float busSpeed = Float.parseFloat(context.getString(R.string.reminder_configs_regular_bus_speed));
		float radius = busSpeed*PROXIMITY_SERVICE_INTERVAL;
		
		Intent intent = new Intent(context.getString(R.string.reminder_intent_action_end_stop));
		intent.putExtra(REMINDER_END_STOP_LOCATION_UPDATE_INTENT_KEY_SOURCE,REMINDER_END_STOP_INTENT_SRC_PROXIMITY_ALERT);
		
		intent.putExtra(REMINDTER_END_STOP_LOCATION_UPDATE_INTENT_KEY_DATA, reminder.createBundle());

		//set data to this stop
		String prefix = context.getString(R.string.reminder_intent_data_uri_end_stop);
		intent.setData(Uri.parse(prefix + reminder.getReminderId()));
		
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
		
		try{
		//insert a reminder record to database
			ReminderDAO rDao = new ReminderDAO(ApplicationDataBase.getSQLiteOpenHelper());
			rDao.insertReminder(reminder);
			
			locMgr.addProximityAlert(destStop.getLatitude(), destStop.getLongitude(), radius, -1, pendingIntent);
			Intent reminderUpdate = new Intent(context.getString(R.string.reminders_tab_end_stop_update));
			context.sendBroadcast(reminderUpdate);
		}catch(SQLiteConstraintException e){
			throw e;
		}		
		
		
		Log.d(LOG_TAG,"an end stop Reminder has been set");
		
	}
	
	public void cancelEndStopReminder(int dbId,String reminderId){
		Intent intent = new Intent(context.getString(R.string.reminder_intent_action_end_stop));
		//set data to this stop
		String prefix = context.getString(R.string.reminder_intent_data_uri_end_stop);
		intent.setData(Uri.parse(prefix + reminderId));
		PendingIntent origPendingIntent = PendingIntent.getBroadcast(context,0, intent, 0);
		LocationManager locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		locManager.removeProximityAlert(origPendingIntent);
		locManager.removeUpdates(origPendingIntent);
		
		deleteReminderByDBIdFromDB(ReminderType.EndStopReminder, dbId);
		
		
	}
	
	
}
